<template>
	<view class="content">
		<view class="navbar">
			<up-navbar title="审批配置" :fixed="false" leftIconColor="#fff" :safeAreaInsetTop="true" :autoBack="true">
			</up-navbar>
		</view>

		<!-- 审批配置 -->
		<view class="fd-nav-content" ref="scrollContainer" v-if="formData.scollViewHeight" :style="{
			height: `${formData.scollViewHeight}px`,
			overflowX: 'hidden',
			overflowY: 'auto'
		}" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd">
			<!-- 缩放控制按钮 -->
			<view class="m-zoom">
				<view :class="'m-zoom-out'+ (formData.nowVal==50?' disabled':'')" @click="zoomSize(1)">-</view>
				<text>{{formData.nowVal}}%</text>
				<view :class="'m-zoom-in'+ (formData.nowVal==300?' disabled':'')" @click="zoomSize(2)">+</view>
			</view>
			<section class="dingflow-design">
				<view class="scale-content">
					<!-- 缩放内容容器 - 添加触摸事件监听双指缩放 -->
					<view class="box-scale" id="box-scale" :style="{
							transform: `scale(${formData.nowVal / 100})`, 
							transformOrigin: '50% 0',
							paddingBottom: '30px'
						}">
						<m-node-warp v-model:nodeConfig.sync="formData.nodeConfig"
							v-model:flowPermission.sync="formData.flowPermission" :isTried.sync="formData.isTried"
							:directorMaxLevel="formData.directorMaxLevel" :tableId="formData.tableId">
						</m-node-warp>
						<view class="end-node">
							<view class="end-node-circle"></view>
							<view class="end-node-text">流程结束</view>
						</view>
					</view>
				</view>
			</section>
		</view>

		<!-- 底部按钮区域保持不变 -->
		<view class="x-f BottomBox"
			:style="{'padding-bottom':formData.safeAreaBottom+'px','height': formData.btnHeight + 'px'}">
			<!-- 弹窗内容保持不变 -->
			<uni-popup ref="showFlowChart" mode="center" :mask-click="false" border-radius="10px 10px 10px 10px">
				<view class="f-dc" style="width: 90vw;max-height: 80vh;min-height: 40vh;background-color: #fff;">
					<u-cell title="发起审批" style="background-color: #51d0d0;"
						:titleStyle="{color: '#fff',fontSize: '12px'}">
						<template slot="right-icon">
							<view @click="closeFlowChart">
								<u-icon name="close" color="#fff" size="16"></u-icon>
							</view>
						</template>
					</u-cell>

					<!-- <view style="flex: 1;overflow: auto;background-color: #fffbea;"> -->
					<mFlowCharts ref="flowCharts" style="flex: 1;overflow: auto;" :option="formData.flowChartData">
					</mFlowCharts>
					<!-- </view> -->

					<view class="x-ec" style="width: 100%;height: 40px;">
						<button class="content_bottom_primary_plainBtn CommonBtnSize" @click="closeFlowChart"
							style="padding: 6px 15px !important;margin-right: 8px;">取消</button>
						<button class="content_bottom_primary_Btn CommonBtnSize" @click="submitFlowChart"
							style="padding: 6px 15px !important;margin-right: 8px;">确定</button>
					</view>

				</view>
			</uni-popup>

			<view class="BottomBox-btnBox">
				<button @click="cancelConfigBtn" class="content_bottom_primary_plainBtn CommonBtnSize">取消</button>
				<button @click="submitConfigBtn" class="content_bottom_primary_Btn CommonBtnSize">确定</button>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
	import { ref, onMounted, computed, reactive, nextTick, watch } from 'vue';
	import { onLoad, onUnload } from "@dcloudio/uni-app";
	import useRequestQueue from '@/uni_modules/mc-ui/libs/http/UniversalRequestQueue';
	const { request, requestByUrl, PromiseRequestByUrl, onAllComplete, onError } = useRequestQueue();
	import { useMainStore, useInventoryStore, useUserStore, usePermissionStore } from '@/store';
	const inventoryStore = useInventoryStore();
	const mainStore = useMainStore();
	const userStore = useUserStore();
	const permissionStore = usePermissionStore();
	import { run } from '@/common/comFun/interpreter'
	let layer = uni.$utils.layer;
	import { useApproval } from '@/common/comFun/approval-flow/approvalFlowHandlers';
	import mFlowCharts from '@/uni_modules/mc-ui/components/m-node-warp/components/m-flow-charts/m-flow-charts.vue';

	const isPinching = ref(false); // 是否正在双指缩放
	const startDistance = ref(0); // 初始双指距离
	const startScale = ref(100); // 初始缩放值
	let formData = reactive<any>({
		positionTop: 44,
		scollViewHeight: 0,
		btnHeight: 60,
		safeAreaBottom: 0,
		isTried: false,
		tipList: [],
		tipVisible: false,
		nowVal: 100,
		BaseScreenParm: {},
		globalData: {},
		processConfig: {},
		nodeConfig: {},
		workFlowDef: {},
		flowPermission: [],
		directorMaxLevel: 0,
		dialogVisible: true,
		tableId: "",

		source: '',

		flowChartData: {},
		eventChannel: null,
	})


	watch(formData.nodeConfig, (nVal : any) => {
		uni.$utils.addZIndex(formData.processConfig.nodeConfig);
		formData.nodeConfig = formData.processConfig.nodeConfig;
		formData.flowPermission = formData.processConfig.flowPermission;
		formData.directorMaxLevel = formData.processConfig.directorMaxLevel;
		formData.workFlowDef = formData.processConfig.workFlowDef;
		formData.tableId = formData.processConfig.tableId;
		inventoryStore.st_comPageConfig.nodeConfig = formData.nodeConfig;
	}, { deep: true });


	function getViewHeight() {
		let res = uni.getSystemInfoSync();

		let safeArea = res.safeAreaInsets as any; // 安全区域嵌入 top - bottom
		let safe = safeArea.top + safeArea.bottom
		// let windowHeight = res.windowHeight - safe; // 总高
		let windowHeight = res.windowHeight; // 总高
		let navHeight = 0;
		setTimeout(() => {
			uni.createSelectorQuery().select('.navbar').boundingClientRect((rect : any) => {
				navHeight = rect.height;
				// let positionTop = navHeight + safeArea.top;
				formData.positionTop = navHeight;


				uni.createSelectorQuery().select('.BottomBox').boundingClientRect((ret : any) => {
					if (uni.getStorageSync('safeAreaBottom')) {
						formData.safeAreaBottom = (+uni.getStorageSync('safeAreaBottom')) / 2;
					}

					let btnHeight = +ret.height + +formData.safeAreaBottom;
					formData.btnHeight = btnHeight;
					let nextData = windowHeight - (+navHeight + btnHeight);
					formData.scollViewHeight = nextData;
				}).exec();

			}).exec();
		}, 300);
	};

	function reErr(data : any) {
		if (data.childNode) {
			if (data.childNode.type == 1) { //审批人
				if (data.childNode.error) {
					formData.tipList.push({
						name: data.childNode.nodeName,
						type: "审核人"
					})
				}
				formData.reErr(data.childNode)
			} else if (data.childNode.type == 2) {
				if (data.childNode.error) {
					formData.tipList.push({
						name: data.childNode.nodeName,
						type: "抄送人"
					})
				}
				formData.reErr(data.childNode)
			} else if (data.childNode.type == 3) {
				formData.reErr(data.childNode.childNode)
			} else if (data.childNode.type == 4) {
				formData.reErr(data.childNode)
				for (let i = 0; i < data.childNode.conditionNodes.length; i++) {
					if (data.childNode.conditionNodes[i].error) {
						formData.tipList.push({
							name: data.childNode.conditionNodes[i].nodeName,
							type: "条件"
						})
					}
					formData.reErr(data.childNode.conditionNodes[i])
				}
			}
		} else {
			data.childNode = null
		}
	};

	function saveSet() {
		formData.isTried = true;
		formData.tipList = [];
		formData.reErr(formData.nodeConfig);
		if (formData.tipList.length != 0) {
			formData.tipVisible = true;
			return;
		}
		formData.processConfig.flowPermission = formData.flowPermission;
	};

	// 双指距离计算函数
	const getDistance = (touches : TouchList) => {
		const dx = touches[0].clientX - touches[1].clientX;
		const dy = touches[0].clientY - touches[1].clientY;
		return Math.sqrt(dx * dx + dy * dy);
	};

	// 触摸开始事件
	const handleTouchStart = (e : TouchEvent) => {
		// 双指触摸时初始化
		if (e.touches.length === 2) {
			isPinching.value = true;
			startDistance.value = getDistance(e.touches);
			startScale.value = formData.nowVal;
		}
	};

	// 触摸移动事件
	const handleTouchMove = (e : TouchEvent) => {
		if (!isPinching.value || e.touches.length !== 2) return;

		// 阻止页面滚动
		e.preventDefault();

		// 计算当前双指距离
		const currentDistance = getDistance(e.touches);
		// 计算缩放比例变化
		const scaleRatio = currentDistance / startDistance.value;
		// 计算新的缩放值（限制在50-300之间）
		let newScale = Math.round(startScale.value * scaleRatio);
		newScale = Math.max(50, Math.min(300, newScale));

		// 更新缩放值
		formData.nowVal = newScale;
	};

	// 触摸结束事件
	const handleTouchEnd = () => {
		isPinching.value = false;
	};

	function zoomSize(type : any) {
		debugger;
		if (type == 1) {
			if (formData.nowVal == 50) {
				return;
			}
			formData.nowVal -= 10;
		} else {
			if (formData.nowVal == 300) {
				return;
			}
			formData.nowVal += 10;
		}
	};
	let showFlowChart = ref<any>(null);
	let showFlowChartBoolean = ref(false);
	function submitConfigBtn() { // 确认按钮

		formData.flowChartData = uni.$utils.deepClone(formData.processConfig);

		// 展示流程
		showFlowChart.value.open();
		showFlowChartBoolean.value = true;
	}

	function cancelConfigBtn() { // 取消按钮
		uni.navigateBack();
	}

	function closeFlowChart() { // 流程弹层取消按钮
		showFlowChart.value.close();
		showFlowChartBoolean.value = false;
	}

	function post(sql ?: any, param ?: any, callBack ?: any) {
		console.log(sql);
		console.log(param);
		param["sql"] = sql;
		try {
			requestByUrl({
				config: {
					baseURL: "/SQLData/QuerySql"
				},
				url: '',
				method: 'POST',
				data: param,
				success(ret : any) {
					console.log(ret);
					callBack(ret);
				},
				fail(err : any) {
					console.log(err);
				}
			});
		} catch (error) {
			console.log(error);
		}

	};

	function submitFlowChart() { // 流程弹层确认按钮
		uni.$utils.showLoading();
		console.log(formData.processConfig);
		let mainSql = ''
		let obj = {}
		if (formData.source == 'QMS') {
			//插入主表信息
			mainSql =
				" insert into SYS_BillAPFlow(Type,BillName,APType,CreateTime,AppConfigStr,FormID) values('999',@BillName,1,getdate(),@AppConfigStr,@FormID) select @@identity as APFlowID ";

			obj = {
				BillName: formData.processConfig.workFlowDef.name,
				AppConfigStr: JSON.stringify(formData.processConfig),
				FormID: formData.globalData.Id
			};
		} else {
			//插入主表信息
			mainSql =
				" insert into SYS_BillAPFlow(Type,BillName,APType,CreateTime,AppConfigStr,APPFormID) values('999',@BillName,1,getdate(),@AppConfigStr,@APPFormID) select @@identity as APFlowID ";

			obj = {
				BillName: formData.processConfig.workFlowDef.name,
				AppConfigStr: JSON.stringify(formData.processConfig),
				APPFormID: formData.globalData.Id
			};
		}
		/*
		//插入主表信息
		let mainSql =
			" insert into SYS_BillAPFlow(Type,BillName,APType,CreateTime,AppConfigStr,APPFormID) values('999',@BillName,1,getdate(),@AppConfigStr,@APPFormID) select @@identity as APFlowID ";
		
		let obj = {
			BillName: formData.processConfig.workFlowDef.name,
			AppConfigStr: JSON.stringify(formData.processConfig),
			APPFormID: formData.globalData.Id
		};
		*/
		try {
			console.log(obj);
			post(mainSql, obj, function (ret : any) {
				let retFlow = ret.data;
				let APFlowID = retFlow.ds[0].APFlowID;
				let appConfigObj = uni.$utils.deepClone(formData.processConfig);
				let aPUserIDs = [],
					classIDs = [];
				for (let q = 0; q < appConfigObj.flowPermission.length; q++) {
					if (appConfigObj.flowPermission[q].type == 1) {
						aPUserIDs.push(appConfigObj.flowPermission[q].targetId);
					} else if (appConfigObj.flowPermission[q].type == 3) {
						classIDs.push(appConfigObj.flowPermission[q].targetId);
					}
				};


				//保存发起人
				let sql =
					'insert into SYS_BillAPFlowDe(APFlowID,APFlowNO,APUserID,RoleIDs,JobLevel,ClassIDs,SignedWay,FlowType) values(@APFlowID,@APFlowNO,@APUserID,@RoleIDs,@JobLevel,@ClassIDs,@SignedWay,@FlowType)';
				post(sql, {
					APFlowID: APFlowID,
					APFlowNO: '0',
					APUserID: aPUserIDs.join(','),
					RoleIDs: '',
					JobLevel: '0',
					ClassIDs: classIDs.join(','),
					SignedWay: '0',
					FlowType: '0'
				}, function () { });


				//保存各级审批及抄送人
				let saveApproveFunc = function (node : any, flowNo : any) {
					let caPUserIDs = [],
						cclassIDs = [],
						croleIDs = []
					let Joblevel = 0;
					let flowType = 0;
					let signedWay = 0;
					for (let k = 0; k < node.nodeUserList.length; k++) {
						if (node.nodeUserList[k].type == 1) {
							caPUserIDs.push(node.nodeUserList[k].targetId);
						} else if (node.nodeUserList[k].type == 3) {
							cclassIDs.push(node.nodeUserList[k].targetId);
						} else if (node.nodeUserList[k].type == 2) {
							croleIDs.push(node.nodeUserList[k].targetId);
						}
					}
					if (node.settype == 7) {
						Joblevel = node.examineEndDirectorLevel;
					}
					if (node.type == 1) {
						flowType = 0;
					} else {
						flowType = 1;
					}
					if (node.examineMode == 1) {
						signedWay = 0;
					} else {
						signedWay = 1;
					}

					post(sql, {
						APFlowID: APFlowID,
						APFlowNO: flowNo,
						APUserID: caPUserIDs.join(','),
						RoleIDs: croleIDs.join(','),
						JobLevel: Joblevel,
						ClassIDs: cclassIDs.join(','),
						SignedWay: signedWay,
						FlowType: flowType
					}, function () { });
					flowNo++;
					if (node.childNode) {
						saveApproveFunc(node.childNode, flowNo);
					}
				};

				saveApproveFunc(appConfigObj.nodeConfig.childNode, 1);

				setTimeout(() => {
					requestByUrl({
						config: {
							baseURL: "/Approve/BgApproval"
						},
						url: '',
						method: 'POST',
						data: {
							approveType: 0,
							tableName: formData.globalData.physicalTableName,
							keyName: formData.BaseScreenParm.keyName,
							keyId: formData.BaseScreenParm.keyValue,
							APFlowID: APFlowID,
							userId: userStore.UserInfo.UserID,
							title: formData.processConfig.workFlowDef.name,
						},
						success(approveRet : any) {
							uni.$utils.showLoading();

							if (approveRet.data.ds[0].status == "500") {
								uni.$utils.msg(approveRet.data.ds[0].msg)
							} else {
								uni.navigateBack({
									delta: 1,
									success() {
										formData.eventChannel.emit('doneConfirm', 0);
									}
								})
							}
						}
					});


				}, 1000)

			})


		} catch (e) {
			uni.$utils.showLoading();
			//TODO handle the exception
		}

	};

	onLoad((option : any) => {

		const pages = getCurrentPages()
		const currentPage = pages[pages.length - 1] as any;
		formData.eventChannel = currentPage.getOpenerEventChannel();



		let BaseScreenParm = uni.$utils.deepClone(mainStore.BaseScreenParm);
		console.log(BaseScreenParm);

		formData.BaseScreenParm = BaseScreenParm;
		formData.processConfig = BaseScreenParm.approveObj;
		formData.globalData = BaseScreenParm.globalData;

		// uni.$utils.addZIndex(formData.processConfig.nodeConfig);
		uni.$utils.addZIndex(formData.processConfig.nodeConfig);
		formData.nodeConfig = formData.processConfig.nodeConfig;
		formData.nodeConfig = formData.processConfig.nodeConfig;
		formData.flowPermission = formData.processConfig.flowPermission;
		formData.directorMaxLevel = formData.processConfig.directorMaxLevel;
		formData.workFlowDef = formData.processConfig.workFlowDef
		formData.tableId = formData.processConfig.tableId

		formData.source = option.source
	});


	onMounted(() => {
		nextTick(() => {

			setTimeout(() => {
				getViewHeight();
			}, 300);
		})
	})

	onUnload(() => {

		formData.eventChannel.emit('cancel');
		uni.$off('gitCellCardInfo' + inventoryStore.st_comPageConfig.nodewarpIndex);

		inventoryStore.st_comPageConfig.nodeConfig = {};
	})
</script>

<style lang="scss" scoped>
	@import "/static/assets/css/nodeWarp/workflow.css";


	/* #ifdef MP-WEIXIN */
	view {
		margin: 0;
		padding: 0;
		box-sizing: border-box;
	}

	/* #endif */

	/* #ifndef MP-WEIXIN */
	* {
		margin: 0;
		padding: 0;
		box-sizing: border-box;
	}

	/* #endif */


	.navbar__content__title {
		font-size: 16px !important;
	}

	// 1. 滚动容器（固定高度，仅垂直滚动）
	.fd-nav-content {
		width: 100%;
		position: relative;
		padding: 0 15px; // 左右留白，避免内容贴边
		will-change: scroll-position; // 优化滚动性能（移动端）
	}

	// 缩放控制按钮（保持原样式，微调间距）
	.m-zoom {
		display: flex;
		align-items: center;
		gap: 15px; // 按钮与百分比文字间距
		position: absolute;
		display: flex;
		-webkit-box-align: center;
		-ms-flex-align: center;
		align-items: center;
		-webkit-box-pack: justify;
		-ms-flex-pack: justify;
		justify-content: space-between;
		height: 80rpx;
		width: 200rpx;
		top: 20rpx;
		right: 20rpx;
		z-index: 10;

		.m-zoom-in,
		.m-zoom-out {
			width: 40rpx;
			height: 40rpx;
			line-height: 40rpx;
			text-align: center;
			font-size: 40rpx;
			background: #fff;
			color: #c1c1cd;
			cursor: pointer;
			background-size: 100%;
			background-repeat: no-repeat
		}


		.m-zoom-out.disabled {
			opacity: .5
		}

		.m-zoom-in.disabled {
			opacity: .5
		}

	}

	// 2. 流程设计区（缩放按钮+内容容器）
	.dingflow-design {
		display: flex;
		flex-direction: column;
		align-items: center; // 缩放按钮和内容居中



		// 3. 内容容器（高度由内容自然撑开，不绑定父容器）
		.scale-content {
			width: 100%;
			max-width: 500px; // 限制最大宽度（避免大屏端内容过宽）
			height: auto; // 关键：高度由内部流程内容决定（原始高度）
			margin: 0 auto; // 水平居中
		}

		// 4. 缩放内容容器（仅视觉缩放，不影响DOM尺寸）
		.box-scale {
			width: 100%;
			height: auto; // 取消原100%高度，由内容撑开
			overflow: visible; // 取消原overflow:auto，滚动由父容器负责
		}
	}

	.error-modal-list {
		width: 455px;
	}

	.BottomBox {
		z-index: 9;
		position: fixed;
		bottom: 0;
		left: 0;
		height: 60px;
		width: 100vw;
		background-color: #fff;

		&-btnBox {
			height: 100%;
			width: 100%;
			display: flex;
			align-items: center;
			justify-content: flex-end;

			.CommonBtnSize {
				padding: 10px 15px !important;
				margin-right: 8px;
			}
		}
	}
</style>